package com.mall.user.services;

import com.mall.user.IKaptchaService;
import com.mall.user.constants.SysRetCodeConstants;
import com.mall.user.dal.entitys.ImageResult;
import com.mall.user.dto.KaptchaCodeRequest;
import com.mall.user.dto.KaptchaCodeResponse;
import com.mall.user.utils.ExceptionProcessorUtils;
import com.mall.user.utils.VerifyCodeUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Service;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 *  ciggar
 * create-date: 2019/8/6-14:45
 */
@Slf4j
@Component
@Service
public class KaptchaServiceImpl implements IKaptchaService {

    @Autowired
    RedissonClient redissonClient;

    private final String KAPTCHA_UUID="kaptcha_uuid";


    @Override
    public KaptchaCodeResponse getKaptchaCode(KaptchaCodeRequest request) {
        KaptchaCodeResponse response=new KaptchaCodeResponse();
        try {
            /**
             * 使用了Java的图形化工具，生成了验证码对象，符合默认长度的验证码
             *
             * String image = capText.getImage.getImage();
             *  这个代码获取到是验证码对象
             *
             *  String code = capText.getCode();
             *  获取图片中额验证码 adfa;
             *
             */
            ImageResult capText = VerifyCodeUtils.VerifyCode(140, 43, 4);
            response.setImageCode(capText.getImg());
            String uuid= UUID.randomUUID().toString();
            /**
             * 产生的验证码code 放到Redis里面
             * key 是 KAPTCHA_UUID + uuid
             * value 是 code
             */
            RBucket rBucket=redissonClient.getBucket(KAPTCHA_UUID+uuid);
            rBucket.set(capText.getCode());
            log.info("产生的验证码:{},uuid:{}",capText.getCode(),uuid);
            rBucket.expire(120, TimeUnit.SECONDS);
            response.setImageCode(capText.getImg());
            /**
             * 返回验证码的uuid
             * uuid 这个 uuid被设置到 Cookie 里面
             * 下次注册的时候，就会把ImageCode通过前端识别展示出来，展示成一个验证码
             * uuid会吧Cookie带过来
             * 用户观测到的验证码code + uuid
             * 那么后端怎么验证呢?
             * 通过uuid 去 redis 密码去真正的code
             * 和用户传过来的code 进行比对
             */
            response.setUuid(uuid);
            response.setCode(SysRetCodeConstants.SUCCESS.getCode());
            response.setMsg(SysRetCodeConstants.SUCCESS.getMessage());
        }catch (Exception e){
            log.error("KaptchaServiceImpl.getKaptchaCode occur Exception :"+e);
            ExceptionProcessorUtils.wrapperHandlerException(response,e);
        }
        return response;
    }

    @Override
    public KaptchaCodeResponse validateKaptchaCode(KaptchaCodeRequest request) {
        KaptchaCodeResponse response=new KaptchaCodeResponse();
        try{
            request.requestCheck();
            // 拼接Redis的 key
            String redisKey = KAPTCHA_UUID+request.getUuid();
            // 获取的对应key 的验证码 code
            RBucket<String> rBucket=redissonClient.getBucket(redisKey);
            String code=rBucket.get();
            //{} 是占位符
            log.info("请求的redisKey={},请求的code={},从redis获得的code={}",redisKey,request.getCode(),code);
            //判空的校验 和 判断请求的code 和从Redis获取的code是否一致
            if(StringUtils.isNotBlank(code)&&request.getCode().equalsIgnoreCase(code)){
                response.setCode(SysRetCodeConstants.SUCCESS.getCode());
                response.setMsg(SysRetCodeConstants.SUCCESS.getMessage());
                return response;
            }
            response.setCode(SysRetCodeConstants.KAPTCHA_CODE_ERROR.getCode());
            response.setMsg(SysRetCodeConstants.KAPTCHA_CODE_ERROR.getMessage());
        }catch (Exception e){
            log.error("KaptchaServiceImpl.validateKaptchaCode occur Exception :"+e);
            ExceptionProcessorUtils.wrapperHandlerException(response,e);
        }
        return response;
    }
}
